Skip to content

Refactor Hero component and enhance accessibility features#32

Merged
jasperteo merged 9 commits intomainfrom
feat/fluid-hero-typography
Apr 5, 2026
Merged

Refactor Hero component and enhance accessibility features#32
jasperteo merged 9 commits intomainfrom
feat/fluid-hero-typography

Conversation

@jasperteo
Copy link
Copy Markdown
Owner

@jasperteo jasperteo commented Apr 5, 2026

Summary by CodeRabbit

  • New Features

    • Button now supports custom rendering and native-button modes.
    • Tabs/description updated for improved blur/opacity animations and highlight behavior.
  • Style

    • Hero heading layout refined for balanced text.
    • Page background gains a fixed radial gradient.
    • Tab corners updated to a rounded-full style.
    • New theme tokens for hero typography and select color.
  • Accessibility

    • More semantic markup (dl, dt, dd, nav, h2) and aria-hidden on decorative elements.

Replace fixed responsive text sizes with a fluid clamp-based `text-hero` token, and swap `<br>` line breaks for `block` spans with `text-balance` for better reflow.
Moves motion animation props and shouldHighlight state from AboutTab/RecruiterTab into the parent TabsPanel render prop, enabling layout-aware animations at the panel level.
Introduces an orange-tinted select color token for light and dark themes and applies it as a fixed radial gradient on the body background.
Uses Base UI's useRender hook to allow Button to render as any element (e.g. Link, anchor) when nativeButton is false, enabling semantic rendering for navigation use cases.
Use dl/dt/dd for experience list, nav for socials, h2 for section headings, and aria-hidden on decorative separators and icons.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

📝 Walkthrough

Walkthrough

Refactors tab animation ownership in Description, adds parent-level highlight state, extends Button API for custom rendering, swaps semantic HTML elements and accessibility attributes, adjusts Hero heading markup and root background, updates ESLint to import oxlint config object, and adds theme tokens for hero text and select color.

Changes

Cohort / File(s) Summary
ESLint Configuration
eslint.config.ts
Switched from loading Oxlint config via oxlint.buildFromOxlintConfigFile("./oxlint.config.ts") to importing oxlintConfig and calling oxlint.buildFromOxlintConfig(oxlintConfig).
Description Component
src/components/description.tsx
Moved motion/blur animation wrappers out of tab children into parent render props; introduced parent shouldHighlight state; AboutTab no longer takes hasInteracted; RecruiterTab now receives shouldHighlight.
Button API & Tabs styling
src/components/ui/button.tsx, src/components/ui/tabs.tsx
Button props type extended to include useRender.ComponentProps<"button">; Button now accepts nativeButton and render and conditionally returns useRender output. TabsTab border-radius changed from rounded-md to rounded-full.
Semantic HTML & Accessibility
src/components/experience.tsx, src/components/socials.tsx, src/routes/index.tsx
Replaced generic elements with semantic tags (dl/dt/dd, h2, nav); added aria-hidden="true" to decorative separators and icons.
Hero & Root Styling
src/components/hero.tsx, src/routes/__root.tsx
Hero heading markup changed from explicit <br/> to block <span>s and updated heading classes; root <body> class now includes a fixed radial gradient alongside existing background class.
Theme tokens
src/styles/globals.css
Added --text-hero and --text-hero--line-height; added --color-select inline theme mapping and defined --select in :root and .dark with distinct oklch values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I hopped through code with nimble feet,
Moved highlights up and tabs to greet,
Buttons that render, styles that sing,
Theme tokens dance — a tiny spring.
Cheers, a carrot-shaped commit to meet! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: refactoring the Hero component with new typography styling and enhancing accessibility across multiple components with semantic HTML and ARIA attributes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/fluid-hero-typography

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/description.tsx`:
- Around line 60-70: The inline ref cleanup that resets shouldHighlight is
causing the highlight to be cleared on every rerender; remove the ref callback
block that returns a cleanup and instead reset shouldHighlight inside the tab
change handler (onValueChange). Specifically: delete the ref={() => { return ()
=> { setShouldHighlight(false); }; }} callback, ensure onAnimationComplete still
calls setShouldHighlight(true) only when the active tab equals RECRUITER, and
add a call to setShouldHighlight(false) in the onValueChange handler (or the
function that updates tab state) so the highlight is reset when the tab actually
changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 05bd9760-7f2d-43f7-946b-f84064369cb0

📥 Commits

Reviewing files that changed from the base of the PR and between 566152c and 1cdfad5.

📒 Files selected for processing (10)
  • eslint.config.ts
  • src/components/description.tsx
  • src/components/experience.tsx
  • src/components/hero.tsx
  • src/components/socials.tsx
  • src/components/ui/button.tsx
  • src/components/ui/tabs.tsx
  • src/routes/__root.tsx
  • src/routes/index.tsx
  • src/styles/globals.css

Move setShouldHighlight(false) to the tab change handler where it
belongs, removing the fragile ref callback cleanup pattern.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/components/description.tsx (1)

57-63: ⚠️ Potential issue | 🟡 Minor

Gate the recruiter highlight trigger to the active tab.

Line 62 is still unconditional. If this wrapper finishes animating while ABOUT is selected, shouldHighlight flips back to true and the resume highlight can re-enable out of sequence.

Suggested fix
 						<motion.div
 							layout
 							initial={{ opacity: 0.25, filter: "blur(4px)" }}
 							animate={{ opacity: 1, filter: "blur(0px)" }}
 							onAnimationComplete={() => {
-								setShouldHighlight(true);
+								if (tab === RECRUITER) {
+									setShouldHighlight(true);
+								}
 							}}
 						/>
For `@base-ui-components/react` Tabs, are inactive `Tabs.Panel` elements mounted by default, and for `motion/react` does `onAnimationComplete` fire for initial/layout animations on mount? I want to verify whether an inactive tab panel can still call `onAnimationComplete`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/description.tsx` around lines 57 - 63, The motion.div's
onAnimationComplete unconditionally calls setShouldHighlight(true), which can
re-enable the resume highlight even when the ABOUT tab is not active; update the
handler to guard by the active tab state/prop (e.g., check activeTab or
currentTab) and only call setShouldHighlight(true) when the active tab equals
the ABOUT tab constant (e.g., "ABOUT" or Tabs.ABOUT). Locate the motion.div
wrapper and modify its onAnimationComplete to first test the active-panel flag
(or selected tab variable) and return early if the panel is not active so the
highlight only triggers for the visible ABOUT panel.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/components/description.tsx`:
- Around line 57-63: The motion.div's onAnimationComplete unconditionally calls
setShouldHighlight(true), which can re-enable the resume highlight even when the
ABOUT tab is not active; update the handler to guard by the active tab
state/prop (e.g., check activeTab or currentTab) and only call
setShouldHighlight(true) when the active tab equals the ABOUT tab constant
(e.g., "ABOUT" or Tabs.ABOUT). Locate the motion.div wrapper and modify its
onAnimationComplete to first test the active-panel flag (or selected tab
variable) and return early if the panel is not active so the highlight only
triggers for the visible ABOUT panel.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 761a624b-ec49-4e69-bf9e-9ebda097edd7

📥 Commits

Reviewing files that changed from the base of the PR and between 1cdfad5 and dc8745f.

📒 Files selected for processing (1)
  • src/components/description.tsx

@jasperteo jasperteo merged commit 1243954 into main Apr 5, 2026
1 check passed
@jasperteo jasperteo deleted the feat/fluid-hero-typography branch April 5, 2026 10:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant